$LOAD_PATH.unshift(File.dirname(__FILE__)) unless $LOAD_PATH.include?(File.dirname(__FILE__))
require 'date'
	
require File.dirname(__FILE__)+'/zddi'


class RUN_TESTSUIT
	def initialize(brow, site, user, password, filename)
		ZDDI.init_browser(brow)
		ZDDI::Login::Login.new.login(site, user, password)   
		sleep 1
		#ZDDI::System_management::Server_management.new.init_server
		#sleep 1
		@f = File.new(File.dirname(__FILE__)+'/case/log/'+filename, "a+")
		@f_cur = File.new(File.dirname(__FILE__)+'/case/log/last_messages.log', "w")
        @case_info = ''
        @suit_info = ''
        @retry = 0
	end
    def close
        ZDDI.browser.close
    end

	def run_case(className, funcName)
		begin
			Timeout::timeout(600) do
				Dir[File.dirname(__FILE__)+'/case/*.rb'].each {|file| 
					if file.match(className.downcase) then
						require file
					end
				}
                cs = Case_stats.new
				k=Kernel.const_get(className).new()
				if k.respond_to?(funcName) then			
                    cs.name = funcName
  					rl = k.send(funcName)
  					rl.each {|r|
  						if r.match("succeed") then
                            cs.add_succ
                            @case_info += "\t#{funcName} pass\n"
  							@f.puts "\t#{funcName} pass"
                            r.split("\n").each {|res|
                                @f.puts "\t\t#{res}\n"
                                @case_info += "\t\t#{res}\n"
                            }
  					    else
                            cs.add_fail
                            @case_info += "\t#{funcName} fail\n"
  							@f.puts "\t#{funcName} fail"
                            r.split("\n").each {|res|
                                @f.puts "\t\t#{res}\n"
                                @case_info += "\t\t#{res}\n"
                            }
  							#run_case(className, funcName)
  					    end
  				    }
  				else
  					@f.puts "class: #{className} has not function: #{funcName}, pls check"
                    puts "class: #{className} has not function: #{funcName}, pls check"
  					@f.puts "\n"
				end 
                @case_info = cs.info + @case_info
                puts cs.info
                return cs
			end
		rescue Timeout::Error => e
			puts e
            @f.puts e
			ZDDI.browser.refresh
			sleep 3
			run_case(className, funcName)
		rescue 
			if ZDDI.browser.html.include?"502 Bad Gateway" then
				puts "website is bad geteway"
				ZDDI.browser.back
				sleep 3
				run_case(className, funcName)
			elsif ZDDI.browser.url.include?"error" then
				puts "website is error"
				ZDDI.browser.back
				sleep 3
				run_case(className, funcName)
			else
                @retry += 1
				puts "error at: #{$@}\n"
				puts "error: #{$!}\n"
				ZDDI.browser.refresh
				sleep 3
                #if @retry < 3
				run_case(className, funcName)
                #else
                #    @f.close
                #    @f_cur.close
                #end
			end	
		end
 
	end


	def run_casesuit(casesuit)
        ss = Suit_stats.new
        casesuit.each_pair{ |className, func_list|
                ss.name = className
				@f.puts "class: #{className} start to test "
				func_list.each{|func|
					cs = run_case(className, func)
                    if cs.total == cs.succ
                        ss.add_succ
                    else
                        ss.add_fail
                    end
				}
                @suit_info += ss.info
				@f.puts "class: #{className} end to test"
  				@f.puts "\n"
            
        }
        puts ss.info
        return ss
	end

	def run_testsuit(testsuit)
        sts = Stream_stats.new
		t = DateTime.now
		@f.puts "!!!start test #{t.strftime("%Y-%m-%d %H:%M:%S")}"
        @f_cur.puts "!!!start test #{t.strftime("%Y-%m-%d %H:%M:%S")}"
		@f.puts "------------------------------------------------------------------------------------------------------------"
		testsuit.each{|cs|
				ss = run_casesuit(cs)
                if ss.total == ss.succ
                    sts.add_succ
                else
                    sts.add_fail
                end
			}
        @f_cur.puts("\ntest point: group, device, view, zone, domain, rr, acl, shared-rr, search\n")
        if sts.succ == sts.total 
            @f_cur.puts("\nall test case pass\n")
        else
            @f_cur.puts("there is #{sts.fail} failed!!!\n\n")
            @f_cur.puts("detail as follows:\n")
        end
        @f_cur.puts(sts.info)
        @f_cur.puts(@suit_info)
        @f_cur.puts(@case_info)
        @f.puts(sts.info)
        @f.puts(@suit_info)
        @f.puts(@case_info)
		@f.puts "------------------------------------------------------------------------------------------------------------"
		t = DateTime.now
        @f_cur.puts "!!!end test #{t.strftime("%Y-%m-%d %H:%M:%S")}"
        @f.puts "!!!end test #{t.strftime("%Y-%m-%d %H:%M:%S")}"
		@f.puts "\n"
	end
    class Stats
        attr_accessor(:succ, :fail, :name)
        def initialize()
            @succ = 0
            @fail = 0
            @name = ''
        end
        def add_succ
            @succ += 1
        end
        def add_fail
            @fail += 1
        end
        def total
            return @succ + @fail
        end
    end
    class Stream_stats < Stats
        def info
            return "Stream=> #{@name}\ttotal: #{total}\tsucc: #{@succ}\tfail: #{@fail}\n"
        end
    end
    class Suit_stats < Stats
        def info
            return "class=> #{@name}\ttotal: #{total}\tsucc: #{@succ}\tfail: #{@fail}\n"
        end
    end
    class Case_stats < Stats
        def info
            return "func=> #{@name}\ttotal: #{total}\tsucc: #{@succ}\tfail: #{@fail}\n"
        end
    end
end


